package jwcb.portal.server.service.impl;

import jwcb.admin.api.user.domain.dto.UserEditReqDTO;
import jwcb.admin.api.user.domain.vo.AppUserVo;
import jwcb.admin.api.user.feign.AppUserFeignClient;
import jwcb.javapjframework.common.core.enums.UserIdentity;
import jwcb.javapjframework.common.core.utils.StringUtil;
import jwcb.javapjframework.common.domain.domain.R;
import jwcb.javapjframework.common.domain.domain.ResultCode;
import jwcb.javapjframework.common.domain.domain.dto.LoginUserDto;
import jwcb.javapjframework.common.domain.exception.ServiceException;
import jwcb.javapjframework.common.security.domain.dto.TokenDto;
import jwcb.javapjframework.common.security.service.TokenService;
import jwcb.javapjframework.common.security.utils.JwtUtil;
import jwcb.javapjframework.common.security.utils.SecurityUtil;
import jwcb.javapjframework.message.service.CaptchaService;
import jwcb.portal.server.domain.dto.LoginDto;
import jwcb.portal.server.domain.dto.PhoneLoginDto;
import jwcb.portal.server.domain.dto.UserDTO;
import jwcb.portal.server.domain.dto.WechatLoginDto;
import jwcb.portal.server.service.IUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 门户用户服务实现层
 */
@Service
public class UserServiceImpl implements IUserService {
    private static final Logger log = LoggerFactory.getLogger(UserServiceImpl.class);
    @Autowired
    private AppUserFeignClient appUserFeignClient;

    @Autowired
    private CaptchaService captchaService;
    @Autowired
    private TokenService tokenService;

    /**
     * 登录逻辑
     * @param loginDto 登录信息
     * @return token信息
     */
    @Override
    public TokenDto login(LoginDto loginDto) {
        LoginUserDto loginUserDto = new LoginUserDto();
        if(loginDto instanceof WechatLoginDto wechatLoginDto) {
            // 微信登录
            loginByWechat(wechatLoginDto,loginUserDto);
        }else if(loginDto instanceof PhoneLoginDto phoneLoginDto) {
            // 手机验证码登录
            loginByPhone(phoneLoginDto,loginUserDto);
        }
        loginUserDto.setUserFrom("app");
        loginUserDto.setUserIdentity(UserIdentity.NORMAL_USER.getValue());
        return tokenService.createToken(loginUserDto);
    }




    /**
     * 发送短信验证码
     * @param phone 手机号
     */
    @Override
    public void sendSmsCode(String phone) {
        captchaService.sendCode(phone);
    }

    /**
     * 修改用户信息
     * @param userEditReqDTO C端用户编辑DTO
     */
    @Override
    public void edit(UserEditReqDTO userEditReqDTO) {
        R<Void> result = appUserFeignClient.edit(userEditReqDTO);
        if (result == null || result.getCode() != ResultCode.SUCCESS.getCode()) {
            throw new ServiceException("修改用户失败");
        }
    }



    /**
     * 获取用户登录信息
     * @return 用户信息DTO
     */
    @Override
    public UserDTO getLoginUser() {
        LoginUserDto loginUserDTO = tokenService.getLoginUserDto();
        if (loginUserDTO == null) {
            throw new ServiceException("用户令牌有误", ResultCode.INVALID_PARA.getCode());
        }
        // 2 远程调用获取用户信息
        R<AppUserVo> result = appUserFeignClient.findById(loginUserDTO.getUserId());
        if (result == null || result.getCode() != ResultCode.SUCCESS.getCode() || result.getData() == null) {
            throw new ServiceException("查询用户失败", ResultCode.INVALID_PARA.getCode());
        }
        // 3 对象拼装，返回结果
        UserDTO userDTO = new UserDTO();
        BeanUtils.copyProperties(loginUserDTO, userDTO);
        BeanUtils.copyProperties(result.getData(), userDTO);
        return userDTO;
    }
    /**
     * 退出登录
     */
    @Override
    public void logout() {
        // 1 解析令牌
        String token = SecurityUtil.getToken();
        if (StringUtil.isEmpty(token)) {
            return;
        }
        String userName = JwtUtil.getUserName(token);
        String userId = JwtUtil.getUserId(token);
        log.info("{}退出了系统, 用户ID{}", userName, userId);
        // 2 删除用户缓存记录
        tokenService.removeLoginStatus(token);
    }


    /**
     * 微信登录
     * @param wechatLoginDto 微信登录DTO
     * @param loginUserDto 用户生命周期对象
     */
    private void loginByWechat(WechatLoginDto wechatLoginDto,LoginUserDto loginUserDto) {
        AppUserVo appUserVo;
        R<AppUserVo> result = appUserFeignClient.findByOpenId(wechatLoginDto.getOpenId());
        if(result == null || result.getCode() != ResultCode.SUCCESS.getCode()) {
            // 请求出错
            log.error("[loginByWechat] -> [findByOpenId] error: {}",result == null ? "res == null" : result.getMsg());
            throw new ServiceException(ResultCode.FAILED);
        }
        if(result.getData() == null) {
            // 进行注册
            appUserVo = register(wechatLoginDto);
        }else {
            appUserVo = result.getData();
        }
        // 设置登录信息
        loginUserDto.setUserId(appUserVo.getId());
        loginUserDto.setUserName(appUserVo.getNickName());
    }


    /**
     * 手机验证码
     * @param phoneLoginDto 手机登录DTO
     * @param loginUserDto 用户生命周期对象
     */
    private void loginByPhone(PhoneLoginDto phoneLoginDto, LoginUserDto loginUserDto) {

        boolean isCodeRight = captchaService.checkCode(phoneLoginDto.getPhone(), phoneLoginDto.getCode());
        if(!isCodeRight) {
            throw new ServiceException(ResultCode.ERROR_CODE);
        }
        AppUserVo appUserVo;
        R<AppUserVo> result = appUserFeignClient.findByPhone(phoneLoginDto.getPhone());
        if(result == null || result.getCode() != ResultCode.SUCCESS.getCode()) {
            // 请求出错
            log.error("[loginByWechat] -> [findByPhone] error: {}",result == null ? "res == null" : result.getMsg());
            throw new ServiceException(ResultCode.FAILED);
        }
        if(result.getData() == null) {
            appUserVo = register(phoneLoginDto);
        }else {
            appUserVo = result.getData();
        }
        // 设置登录信息
        loginUserDto.setUserId(appUserVo.getId());
        loginUserDto.setUserName(appUserVo.getNickName());
    }

    /**
     * 根据入参来进行注册
     * @param loginDto 用户信息
     * @return 用户VO
     */
    private AppUserVo register(LoginDto loginDto) {
        R<AppUserVo> result = null;
        if(loginDto instanceof WechatLoginDto wechatLoginDto) {
            result = appUserFeignClient.registerByOpenId(wechatLoginDto.getOpenId());
            if(result == null || result.getCode() != ResultCode.SUCCESS.getCode() || result.getData() == null) {
                log.error("[register] -> [registerByOpenId] error: {}",result == null ? "res == null" : result.getMsg());
            }
        }else if(loginDto instanceof PhoneLoginDto phoneLoginDto) {
            result = appUserFeignClient.registerByPhone(phoneLoginDto.getPhone());
            if(result == null || result.getCode() != ResultCode.SUCCESS.getCode() || result.getData() == null) {
                log.error("[register] -> [registerByPhone] error: {}",result == null ? "res == null" : result.getMsg());
            }
        }
        return result == null ? null : result.getData();
    }
}
